from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets, mixins
from rest_framework.decorators import action
from rest_framework.response import Response

from BYD_ERP.utils.base_views import MultipleDestroyMixin
from BYD_ERP.utils.pagination import GlobalPagination
from production_info.models import DailyProductTaskModel
from production_info.serializer.daily_product_task_serializer import DailyProductTaskSerializer, \
    DailyProductGetMaterialsSerializer, DailyProductBackMaterialsSerializer


class DailyProductTaskViewSets(viewsets.ModelViewSet, MultipleDestroyMixin):
    """
        create:
        每日生产任务--新增，注意：如果有BOM表，则直接读取BOM，如果没有需要自己添加生产物料和工序

        每日生产任务新增，status：201（成功），return：新增每日生产任务信息

        destroy:
        每日生产任务--删除

        每日生产任务删除，status：204（成功），return：None

        multiple_delete:
        每日生产任务--批量删除，必传参数：ids=[1,2,3,4...]

        每日生产任务批量删除，status：204（成功），return：None

        update:
        每日生产任务--修改，注意：其中images_list="1,2,3,4"；里面是附件的ID

        每日生产任务修改，status：200（成功），return：修改后的每日生产任务信息

        partial_update:
        每日生产任务--局部修改，可以传参任意属性的值，服务器会修改指定的属性值

        每日生产任务局部修改，status：200（成功），return：修改后的每日生产任务信息

        list:
        每日生产任务列表--该接口可以弃用

        每日生产任务列表信息，status：200（成功），return：每日生产任务信息列表

        retrieve:
        查询某个每日生产任务

        查询指定ID的每日生产任务，status：200（成功），return：每日生产任务
    """

    queryset = DailyProductTaskModel.objects.all()
    serializer_class = DailyProductTaskSerializer
    pagination_class = GlobalPagination

    def get_queryset(self):
        if self.action == 'find':   # 过滤查询
            # 获取请求参数（在json中）：
            keyword = self.request.data.get('keyword', None)
            partner_name = self.request.data.get('partner_name', None)
            section_name = self.request.data.get('section_name', None)
            glue_name = self.request.data.get('glue_name', None)       # 胶料：X13/X8/X10/X11等
            rope = self.request.data.get('rope', None)                 # 线绳：2*5/2*3等
            start_date = self.request.data.get('start_date', None)
            end_date = self.request.data.get('end_date', None)
            number_code = self.request.data.get('number_code', None)
            remark = self.request.data.get('remark', None)
            query = Q()
            if keyword:
                child_query = Q()
                child_query.add(Q(daily_product_task_item_list__name__contains=keyword), 'OR')
                child_query.add(Q(daily_product_task_item_list__specification__contains=keyword), 'OR')
                child_query.add(Q(daily_product_task_item_list__model_number__contains=keyword), 'OR')
                query.add(child_query, 'AND')
            if partner_name:
                query.add(Q(daily_product_task_item_list__partner_name__contains=partner_name), 'AND')
            if section_name:
                query.add(Q(daily_product_task_item_list__section_name__contains=section_name), 'AND')
            if glue_name:
                query.add(Q(daily_product_task_item_list__glue_name__contains=glue_name), 'AND')  # 胶料
            if rope:
                query.add(Q(daily_product_task_item_list__rope__contains=rope), 'AND')  # 线绳
            if start_date:
                query.add(Q(task_date__gt=start_date), 'AND')
            if end_date:
                query.add(Q(task_date__lt=end_date), 'AND')
            if number_code:
                query.add(Q(number_code__contains=number_code), 'AND')  # 单据编号
            if remark:
                query.add(Q(remark__contains=remark), 'AND')

            return DailyProductTaskModel.objects.filter(query).distinct().all()
        else:
            return DailyProductTaskModel.objects.all()

    params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
        'keyword': openapi.Schema(type=openapi.TYPE_STRING, description="名称的关键字或件号、型号"),
        'partner_name': openapi.Schema(type=openapi.TYPE_STRING, description="厂家"),
        'section_name': openapi.Schema(type=openapi.TYPE_STRING, description="断面"),
        'glue_name': openapi.Schema(type=openapi.TYPE_STRING, description="胶料"),
        'rope': openapi.Schema(type=openapi.TYPE_STRING, description="线绳"),
        'start_date': openapi.Schema(type=openapi.TYPE_STRING, description="起始日期2024-2-24"),
        'end_date': openapi.Schema(type=openapi.TYPE_STRING, description="结束日期2024-2-24"),
        'number_code': openapi.Schema(type=openapi.TYPE_STRING, description="单据编号"),
        'remark': openapi.Schema(type=openapi.TYPE_STRING, description="备注/摘要"),
    })

    # 分页参数必须是query_param（看源码）
    page_param = openapi.Parameter(name='page', in_=openapi.IN_QUERY, description="页号", type=openapi.TYPE_STRING)
    size_param = openapi.Parameter(name='page_size_user_defined', in_=openapi.IN_QUERY, description="每页显示的数量",
                                   type=openapi.TYPE_STRING)

    @swagger_auto_schema(method='post', request_body=params, manual_parameters=[page_param, size_param],
                         operation_description="每日生产计划的过滤查询")
    # swagger_auto_schema中如果method='get'， 是不能用request_body=open_ids的
    # request_body就是定义json格式的传参
    @action(methods=['post'], detail=False)
    def find(self, request, *args, **kwargs):
        return super(DailyProductTaskViewSets, self).list(request=request, *args, **kwargs)

    # 车间每天生产任务单领料
    @swagger_auto_schema(method='post', request_body=DailyProductGetMaterialsSerializer, manual_parameters=[page_param, size_param],
                         operation_description="每日生产任务的领取物料")
    @action(methods=['post'], detail=False)
    def get_daily_product_materials(self, request, *args, **kwargs):
        # return super(DailyProductTaskViewSets, self).create(request=request, *args, **kwargs)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        result = serializer.save()

        return Response({'msg': 'OK'})

    # 车间每天生产任务单退料
    @swagger_auto_schema(method='post', request_body=DailyProductBackMaterialsSerializer,
                         manual_parameters=[page_param, size_param],
                         operation_description="每日生产任务的退还物料")
    @action(methods=['post'], detail=False)
    def back_daily_product_materials(self, request, *args, **kwargs):
        # return super(DailyProductTaskViewSets, self).create(request=request, *args, **kwargs)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        result = serializer.save()

        return Response({'msg': 'OK'})

    def get_serializer_class(self):
        if self.action == 'get_daily_product_materials':
            return DailyProductGetMaterialsSerializer
        elif self.action == 'back_daily_product_materials':
            return DailyProductBackMaterialsSerializer
        else:
            return DailyProductTaskSerializer
